package at.ac.tuwien.big.we14.lab2.servlet;

import at.ac.tuwien.big.we14.lab2.api.Category;
import at.ac.tuwien.big.we14.lab2.api.Choice;
import at.ac.tuwien.big.we14.lab2.api.Game;
import at.ac.tuwien.big.we14.lab2.api.PlayersStatus;
import at.ac.tuwien.big.we14.lab2.api.PlayersStatus.Status;
import at.ac.tuwien.big.we14.lab2.api.QuestionDataProvider;
import at.ac.tuwien.big.we14.lab2.api.QuizFactory;
import at.ac.tuwien.big.we14.lab2.api.impl.ServletQuizFactory;
import at.ac.tuwien.big.we14.lab2.api.impl.SimplePlayersStatus;
import at.ac.tuwien.big.we14.lab2.api.Question;

import java.io.IOException;
import java.io.PrintWriter;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;

import static java.lang.System.out;

import java.util.Random;

import javax.servlet.RequestDispatcher;
import javax.servlet.ServletContext;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;

public class BigQuizServlet extends HttpServlet {
    
    QuizFactory quizfactory;
    List <Game> games;
    
    @Override
    public void init() throws ServletException {
        super.init();
        quizfactory = ServletQuizFactory.init(getServletContext());
        games = new ArrayList<>();
    }
    
    
    @Override
    protected void doGet(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {
    	/* Start Page */
    	RequestDispatcher dispatcher;
    	dispatcher = getServletContext().getRequestDispatcher("/start.jsp");
    	dispatcher.forward(request, response);
    }
    
    
    
    @Override
    protected void doPost(HttpServletRequest request, HttpServletResponse response)
    		throws ServletException, IOException {
    	
    	/* no action no service */
    	String action = request.getParameter("action");
        if(action==null) return;
        
        /* (create || get) session */
        HttpSession session = request.getSession(true);
        String session_id = session.getId();
        /* lookup for games */
    	int game_key = lookup_game(session_id);
    	Game game;
    	
    	if(game_key<0) {
    		/*if no game found, create one*/
    		game = quizfactory.createGame();
    		
    		game.getPlayersId()[0]=session_id;
    		game.getPlayersId()[1]=Game.NONE;
    		
    		game.setPlayersId(game.getPlayersId(),quizfactory);
    		
    		games.add(game);  		
    	}else {
    		/*if game found add player*/
    		game=games.get(game_key);
    		if(game.getPlayersId()[1]==Game.NONE && game.getPlayersId()[0]!=session_id) {
    			game.getPlayersId()[1]=session_id;
    			game.setPlayersId(game.getPlayersId(),quizfactory);
    		}
    		if(game.isOver(session_id)) {
    			/*if found game is Over create new one*/
    			games.remove(game_key);
    			game = quizfactory.createGame();
        		game.getPlayersId()[0]=session_id;
        		game.getPlayersId()[1]=Game.NONE;
        		game.setPlayersId(game.getPlayersId(),quizfactory);
        		games.add(game);
    		}
    	}
    	
    	if(request.getParameter("timeleftvalue")!=null) {
    		/* Answer Mode */
    		String[] answers = request.getParameterValues("answer");
    		Question played_question = game.getQuestionToPaly(session_id, quizfactory);
    		
    		/* calc time needed */
    		long time_needed = played_question.getMaxTime()-Integer.parseInt(request.getParameter("timeleftvalue"));
    		
    		/* check if answer is correct or not */
    		if(answers!=null) {
	    		int[] answers_id = new int[answers.length];
	    		for(int i=0; i<answers_id.length; i++) answers_id[i]=Integer.parseInt(answers[i]);        			
	    		
	    		int question_count=0;
	    		
	    		List<Choice> all = played_question.getAllChoices();
	    		for(int i=0; i<answers_id.length; i++) {
	    			for(Choice choise : played_question.getCorrectChoices()) {
	    				if(choise.equals(all.get(answers_id[i]))) {
	    					question_count++;
	    				}
	    			}
	    		}
	    		boolean correct;
	    		if(question_count!=played_question.getCorrectChoices().size()) {
	    			correct=false;
	    		}else correct=true;	    		
	    		game.setQuestionResult(session_id, played_question, correct, time_needed);
    		} else game.setQuestionResult(session_id, played_question, false, time_needed);
    		
    	}
    	    	
    	RequestDispatcher dispatcher;
        
    	/* Add the right data to the session for the templates and set the right template*/
        if(action.equals(Game.ACTION_GAME) || action.equals(request.getContextPath()+"/"+Game.ACTION_GAME)) {
        	/* Apply Data to Session */
        	session.setAttribute("question", game.getQuestionToPaly(session_id, quizfactory));
        	PlayersStatus status = game.getStatus(session_id, game.ACTION_GAME, quizfactory);
        	status.setNextPage(request.getContextPath()+"/"+status.getNextPage());
        	session.setAttribute("playerstatus", status);
            /* Template */
            dispatcher = getServletContext().getRequestDispatcher("/question.jsp");
        }else if(action.equals(Game.ACTION_ROUNDCOMPLETE) || action.equals(request.getContextPath()+"/"+Game.ACTION_ROUNDCOMPLETE)) {
        	/* Apply Data to Session */
        	PlayersStatus status = game.getStatus(session_id, Game.ACTION_ROUNDCOMPLETE, quizfactory);
        	status.setNextPage(request.getContextPath()+"/"+status.getNextPage());
        	session.setAttribute("playerstatus", status);
        	/* Template */
            dispatcher = getServletContext().getRequestDispatcher("/roundcomplete.jsp");
        }else if(action.equals(Game.ACTION_FINISH) || action.equals(request.getContextPath()+"/"+Game.ACTION_FINISH)) {
        	/* Apply Data to Session */
        	PlayersStatus status = game.getStatus(session_id, Game.ACTION_FINISH, quizfactory);
        	status.setNextPage(request.getContextPath()+"/"+status.getNextPage());
        	session.setAttribute("playerstatus", status);
        	/* null terminate game */
        	game.setQuestionResult(session_id, null, false, 0);
        	/* Template */
            dispatcher = getServletContext().getRequestDispatcher("/finish.jsp");
        }else return;
        
        //dispatch
        dispatcher.forward(request, response);
    }
    
    /* Looks for active games that are not over */
    private int lookup_game(String session_id) {
    	for(int k=0; k<games.size(); k++) {
    		for(int i=0; i<2; i++) {
    			if((games.get(k).getPlayersId()[i]==session_id  ||
    					games.get(k).getPlayersId()[i]==Game.NONE) && !games.get(k).isOver(session_id)) 
    				return k;
    		}
    	}
    	return -1;
    }
 
}